package com.example.shkjdemo.camera2

import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.pm.PackageManager
import android.graphics.*
import android.hardware.camera2.*
import android.hardware.camera2.CameraDevice.TEMPLATE_PREVIEW
import android.media.ImageReader
import android.os.*
import android.util.Log
import android.view.SurfaceHolder
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.databinding.DataBindingUtil
import com.common.commonlibrary.utils.FileUtils
import com.example.shkjdemo.R
import com.example.shkjdemo.databinding.ActivityCamera2Binding
import java.io.*
import java.util.*
import java.util.concurrent.Semaphore
import java.util.concurrent.TimeUnit


class Camera2Activity : AppCompatActivity() {
    private val TAG = "Camera2Activity"
    lateinit var binding: ActivityCamera2Binding
    lateinit var mCameraOpenCloseLock: Semaphore
    //    相机设备类，和Camera1中的Camera同级
    var mCameraDevice: CameraDevice? = null
    //    相机系统服务，用于管理和连接相机设备
    private lateinit var mCameraManager: CameraManager

    private lateinit var mCameraId: String

    private lateinit var mActivity: Activity
    /**预览窗口Holder */
    private var mSurfaceHolder: SurfaceHolder? = null
    /**子线程Handler */
    private var mChildHandler: Handler? = null
    /**主线程Handler */
    private var mMainHandler: Handler? = null

    /**照相会话*/
    private var mCameraCaptureSession: CameraCaptureSession? = null
    /**
     * An [ImageReader] that handles still image capture.
     */
    private var mImageReader: ImageReader? = null


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_camera2)

        mActivity = this
        mSurfaceHolder = binding.svImg.holder
//        保持亮屏
        mSurfaceHolder!!.setKeepScreenOn(true)

        initCamera2()

        getCameraIds()

        listener()
    }

    private fun initCamera2() {
        // 创建Handler线程并启动
        val handlerThread = HandlerThread("Camera")
        handlerThread.start();
        // 创建子线程Handler
        mChildHandler = Handler(handlerThread.looper)
        // 创建主线程Handler
        mMainHandler = Handler(Looper.getMainLooper())

        // 创建图片读取器
        mImageReader = ImageReader.newInstance(176, 144, ImageFormat.JPEG, 1)

        // 图片读取器设置图片可用监听
        mImageReader!!.setOnImageAvailableListener({ reader ->
            run {
                Log.e(TAG, "读取预览数据....")

                showImage(reader)
            }
        }, mMainHandler)

        mCameraManager = getSystemService(Context.CAMERA_SERVICE) as CameraManager
    }

    /**
     * 获取相机信息,默认获取前置摄像头
     * */
    private fun getCameraIds() {
        for (id in mCameraManager.cameraIdList) {
            val characteristics = mCameraManager.getCameraCharacteristics(id)
            var facing = characteristics.get(CameraCharacteristics.LENS_FACING)

            if (null != facing && facing == CameraCharacteristics.LENS_FACING_BACK) {
                mCameraId = id
//                获取摄像头级别
                val level = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL)
                val fpsRanges =
                    characteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES)

                Log.d("FPS", "SYNC_MAX_LATENCY_PER_FRAME_CONTROL: " + Arrays.toString(fpsRanges))

                Log.e(TAG, "摄像头id...$mCameraId 摄像头级别...$level")

                val streamConfigurationMap =
                    characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
                val supportedSizes =
                    streamConfigurationMap?.getOutputSizes(SurfaceTexture::class.java)



                for (size in supportedSizes!!.indices) {

                    Log.e(
                        TAG,
                        "size...width*height = " + supportedSizes[size].width + "*" + supportedSizes[size].height
                    )
                }

                continue
            }
        }


    }

    private fun listener() {
        binding.btnPhoto.setOnClickListener {
            openCamera()
        }
        binding.btnStopPhoto.setOnClickListener {
            onStop()
        }
    }

    private fun openCamera() {
        try {
            mCameraOpenCloseLock = Semaphore(1)
            if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {
                throw RuntimeException("Time out waiting to lock camera opening.")
            }
            if (ActivityCompat.checkSelfPermission(
                    this,
                    Manifest.permission.CAMERA
                ) != PackageManager.PERMISSION_GRANTED
            ) {
                Log.e(TAG, "没有权限...")
                return
            } else {
                mCameraManager.openCamera(mCameraId, mStateCallback, mMainHandler)
                Log.e(TAG, "打开摄像头成功...")
            }
        } catch (e: Exception) {
            e.printStackTrace()
            Log.e(TAG, "打开摄像头失败...", e)
        }

    }


    /**
     * 图片可用后，读取并显示图片
     * @param reader 图片读取器
     */
    private fun showImage(reader: ImageReader) {
        // 拿到图片数据
        var image = reader.acquireNextImage()
        // 获取字节缓冲
        var buffer = image.planes[0].buffer
        // 创建与缓冲区相同的字节数组
        var bytes: ByteArray = ByteArray(buffer.remaining())
        // 将数据读取字节数组
        buffer.get(bytes)

        try {
            // 创建图片
            val bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
            var newBitmap = Bitmap.createBitmap(144, 176, bitmap.getConfig());

            val canvas = Canvas(newBitmap);
            val paint = Paint();
            val matrix = Matrix();
            //图片镜像并旋转90度
            matrix.setScale(-1f, 1f);
            matrix.postTranslate(bitmap.width.toFloat(), 0f);
            matrix.postRotate(90f, bitmap.width.toFloat() / 2, bitmap.height.toFloat() / 2);
            matrix.postTranslate(0f, (bitmap.width.toFloat() - bitmap.height) / 2);

            canvas.drawBitmap(bitmap, matrix, paint)
            val newFile = FileUtils.createFile(
                Environment.getExternalStorageDirectory().absolutePath + "/abs",
                "345.jpeg"
            )
            val file = File(newFile)
            val bos = BufferedOutputStream(FileOutputStream(file));
            newBitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);

            // 显示图片
            if (null != newBitmap) {
                binding.ivPreview.setImageBitmap(newBitmap)
            }
            bos.flush();
            bos.close();
            bitmap.recycle();
            newBitmap.recycle();
        } catch (e: FileNotFoundException) {
            e.printStackTrace();
            Log.e(TAG, "FileNotFoundException", e)
        } catch (e: IOException) {
            e.printStackTrace();
            Log.e(TAG, "IOException", e)
        } finally {

            image.close();
            buffer.clear();
        }

    }

    /**
     * 预览
     * */
    private fun takePreview() {
        try {
            // 创建预览需要的CaptureRequest.Builder
            val builder = mCameraDevice!!.createCaptureRequest(TEMPLATE_PREVIEW)
            // 将SurfaceView的surface作为Builder的目标
            builder.addTarget(mSurfaceHolder!!.surface)
            // 设置预览回调的 Surface
            builder.addTarget(mImageReader!!.surface)
            // 创建CameraCaptureSession,该对象负责管理处理预览请求和拍照请求
            mCameraDevice!!.createCaptureSession(
                listOf(mSurfaceHolder!!.surface, mImageReader!!.surface),
                object : CameraCaptureSession.StateCallback() {

                    override fun onConfigureFailed(session: CameraCaptureSession) {
                        Toast.makeText(mActivity, "配置失败", Toast.LENGTH_SHORT).show()

                    }

                    override fun onConfigured(session: CameraCaptureSession) {
                        if (null == mCameraDevice) {
                            return
                        }
                        // 配置
                        // 当摄像头已经准备好时，开始显示预览
                        mCameraCaptureSession = session
                        try {
                            // 自动对焦
                            builder.set(
                                CaptureRequest.CONTROL_AF_MODE,
                                CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE
                            )
                            // 打开闪光灯
                            builder.set(
                                CaptureRequest.CONTROL_AE_MODE,
                                CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH
                            )
                            // 显示预览
                            var request: CaptureRequest = builder.build()
                            // 会话设置重复请求
                            mCameraCaptureSession!!.setRepeatingRequest(
                                request,
                                mCallbackListener,
                                mChildHandler
                            )
                        } catch (e: CameraAccessException) {
                            e.printStackTrace()
                        }
                    }
                },
                mChildHandler
            )
        } catch (e: CameraAccessException) {
            e.printStackTrace()
            Log.e(TAG, "摄像头访问异常...", e)
        }

    }


    private val mCallbackListener: CameraCaptureSession.CaptureCallback =
        object : CameraCaptureSession.CaptureCallback() {
            override fun onCaptureCompleted(
                session: CameraCaptureSession,
                request: CaptureRequest,
                result: TotalCaptureResult
            ) {
                super.onCaptureCompleted(session, request, result)

            }
        }

    private val mStateCallback: CameraDevice.StateCallback = object : CameraDevice.StateCallback() {
        override fun onOpened(camera: CameraDevice) {
            mCameraOpenCloseLock.release()
            mCameraDevice = camera
//            开始预览
            takePreview()
        }

        override fun onDisconnected(camera: CameraDevice) {
            mCameraOpenCloseLock.release()
            camera.close()
            mCameraDevice = null
        }

        override fun onError(camera: CameraDevice, error: Int) {
            mCameraOpenCloseLock.release()
            camera.close()
            mCameraDevice = null
        }

        override fun onClosed(camera: CameraDevice) {
            super.onClosed(camera)
            mCameraOpenCloseLock.release()
            camera.close()
            mCameraDevice = null
        }
    }

    override fun onStop() {
        super.onStop()
        if (mCameraDevice != null) {
            mCameraDevice!!.close()
            mCameraDevice = null

        }
        if (mImageReader != null) {
            mImageReader!!.close()
            mImageReader = null
        }

    }

    override fun onDestroy() {
        super.onDestroy()
        if (mCameraDevice != null) {
            mCameraDevice!!.close()
            mCameraDevice = null
        }
        if (mImageReader != null) {
            mImageReader!!.close()
            mImageReader = null
        }
        try {
            if (mCameraCaptureSession != null) {
                mCameraCaptureSession!!.abortCaptures();
            }
        } catch (e: Exception) {
            Log.e(TAG, "关闭会话异常...", e)
        } finally {
            mCameraCaptureSession = null
        }
    }
}
